#include<iostream>
using namespace std;
#include<algorithm>
#include<queue>
#include<vector>

#if 0
/********************** 区间选点 *************************/
// 按右端点排序，记录上个区间的右端点end
// 如果当前区间左端点 <= end, 说明end可以覆盖当前区间，直接pass；
// 如果当前区间左端点 > end, 说明end不能覆盖当前区间，点数 +1, 刷新end
const int N = 1e5 + 10;
struct Range
{
    int l, r;
    bool operator<(const Range& R) const
    {
        return r < R.r;
    }
}arr[N];

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        int a, b;
        cin >> a >> b;
        arr[i] = { a,b };
    }
    sort(arr, arr + n);
    int end = -2e9, cnt = 0;
    for(int i = 0; i < n; ++i)
    {
        if(arr[i].l > end)
        {
            end = arr[i].r;
            ++cnt;
        }
    }
    printf("%d", cnt);
    return 0;
}

/******************* 最大不相交的区间数量 ******************/
// 虽然此题与区间选点略有差异，但代码都一样
// 按右端点排序，记录上个区间的右端点end
// 如果当前区间左端点 <= end, 说明有交集，pass掉
// 当前区间左端点 > end, 则没有交集，个数 +1，刷新end
const int N = 1e5 + 10;
struct Range
{
    int l, r;
    bool operator<(const Range& R) const{
        return r < R.r;
    }
}arr[N];

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        int a, b;
        cin >> a >> b;
        arr[i] = { a,b };
    }
    sort(arr, arr + n);
    int end = -2e9, cnt = 0;
    for(int i = 0; i < n; ++i)
    {
        if(arr[i].l > end)
        {
            ++cnt;
            end = arr[i].r;
        }
    }
    printf("%d", cnt);
    return 0;
}
#endif

/********************** 区间分组 *************************/

#if 0

/********************** 区间覆盖 *************************/
const int N = 1e5 + 10;
struct Range{
    int l, r;
    bool operator<(const Range& R) const
    {
        return l < R.l;
    }
}arr[N];
// 按左端点排序，枚举能覆盖start的区间中选择右端点靠右的那个，更新start
int main()
{
    int n, start, end;
    scanf("%d %d %d", &start, &end, &n);
    for(int i = 0; i < n; ++i) {
        int a, b;
        scanf("%d %d", &a, &b);
        arr[i] = { a,b };
    }
    sort(arr, arr + n);

    int cnt = 0; 
    bool flag = false; // 置为true会出bug
    for(int i = 0; i < n; ++i)
    {
        int j = i, right = -2e9; // 为什么right放外面就会TLE？
        // 枚举可能覆盖start的区间，选择右端点最靠右的那个
        while(j < n && arr[j].l <= start)
        {
            right = max(right, arr[j].r);
            ++j;
        }
        ++cnt;
        // 右端点最靠右的都不能覆盖start，说明无区间可以覆盖
        if(right < start)
        {
            flag = false;
            break;
        }
        // 若更新后start已超过end，直接返回true
        start = right;
        if(start >= end)
        {
            flag = true;
            break;
        }
        i = j - 1;
    }
    if(!flag) cnt = -1;
    printf("%d", cnt);
    return 0;
}

/********************** Huffman树类型 *******************/
// 合并果子：https://www.acwing.com/problem/content/150/
int arr[10010];
int main()
{
    int n, ret = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", &arr[i]);
    priority_queue<int, vector<int>, greater<int>> pq(arr, arr + n);
    while(pq.size() != 1)
    {
        int a = pq.top(); pq.pop();
        int b = pq.top(); pq.pop();
        ret += a + b;
        pq.push(a + b);
    }
    printf("%d", ret);
    return 0;
}

/********** 排队打水 **************/
int arr[100010];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", &arr[i]);
    sort(arr, arr + n);

    //ret记录总等待时间，pre记录上一个人的等待时间
    long long ret = 0, pre = 0;
    for(int i = 0; i < n - 1; ++i)
    {
        ret += pre + arr[i];
        pre += arr[i]; //上一个人的等待时间 + 当前打水需要的时间就是下一个人的等待时间
    }
    
    // // t1, t2, t3 ... tn
    // // 总等待时间 = t1*(n-1) + t2*(n-2) + t3*(n-3) ... + tn-1 * 1
    // long long ret = 0, a = n - 1;
    // for(int i = 0; i < n - 1; ++i)
    // {
    //     ret += arr[i] * a;
    //     --a;
    // }
    printf("%lld", ret);
    return 0;
}

/********** 数轴上求一个点，使其到所有点的距离之和最小 **************/
// 货仓选址：https://www.acwing.com/problem/content/106/

// 绝对值不等式，直接取中位数即可。
// 奇数个取中间的那个数，偶数个取中间两对数闭区间任意一点，可以取端点
// 从小到大排序，令所求的点为 x
// f(x) = |x1 - x| + |x2 - x| + ... + |xn - x|
//      = (|x1 - x| + |xn - x|) + (|x2 - x| + |xn-1 - x|) + ...
// 由于|x1 - x| + |xn - x| >= xn - x1, 当x取[x1, xn]区间时等号成立
// f(x) >= (xn - x1) + (xn-1 - x2) + ... 当x取[x1, xn]交[x2, xn-1]交[x3, xn-2]... 即中位数(区间) 时等号成立
int arr[100010];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", &arr[i]);
    sort(arr, arr + n);
    int t = arr[(n - 1) / 2];
    long long ret = 0;
    for(int i = 0; i < n; ++i)
    {
        ret += abs(arr[i] - t);
    }
    printf("%lld", ret);
    return 0;
}

/*补：二维绝对值不等式、柯西不等式
费马点、欧几里得距离、模拟退火

*/
#endif

/***************** 叠罗汉 ****************/
// 按体重+强壮程度 从小到大区排序即可
struct P
{
    int w, s;
    bool operator<(const P& p1) const
    {
        return w + s < p1.w + p1.s;
    }
}arr[50010];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
    {
        int a, b;
        scanf("%d %d", &a, &b);
        arr[i] = { a,b };
    }
    sort(arr, arr + n);
    long long sum_w = 0; 
    int ans = -2e9;
    for(int i = 0; i < n; ++i)
    {
        ans = max((long long)ans, sum_w - arr[i].s); // ans: int, 后一项: long long, max无法实例化
        sum_w += arr[i].w;
    }
    printf("%d", ans);
    return 0;
}